#!/bin/bash
# Copyright (C) 2019 Checkmk GmbH - License: GNU General Public License v2
# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and
# conditions defined in the file COPYING, which is part of this source code package.

#
# BEGIN COMMON INVENTORY CODE
#

# Reason for this no-op: shellcheck disable=... before the first command disables the error for the
# entire script.
:

# Disable unused variable error (needed to keep track of version)
# shellcheck disable=SC2034
CMK_VERSION="2.5.0b1"

_load_config() {
    # defaults:
    INVENTORY_INTERVAL=$((3600 * 4))

    [ -r "${1}" ] || return
    # shellcheck source=../cfg_examples/mk_inventory.cfg
    . "${1}"
}

inpath() {
    # replace "if type [somecmd]" idiom
    # 'command -v' tends to be more robust vs 'which' and 'type' based tests
    command -v "${1:?No command to test}" >/dev/null 2>&1
}

_get_epoch() {
    # This is taken from the check_mk_agent. Try to keep it in sync with set_up_get_epoch...

    # On some systems date +%s returns a literal %s
    if date +%s | grep "^[0-9].*$" >/dev/null 2>&1; then
        date +%s
    else
        # do not check whether perl is even present.
        # in weird cases we may be fine without get_epoch.
        perl -e 'print($^T."\n");'
    fi
}

_insert_persist_option() {
    # insert the persist(...) option, if it is not already present.
    sed -e '/^<<<.*\(:persist(\).*>>>/{p;d;}' -e 's/^<<<\([^>]*\)>>>$/<<<\1:persist('"${1}"')>>>/'
}

run_persisted() {
    INTERVAL="${1}"
    shift

    FLAGFILE="${MK_VARDIR}/persisted/${1}.${REMOTE}"
    NOW="$(_get_epoch)"
    UNTIL=$((NOW + INTERVAL + 600))
    LAST_RUN="$(cat "${FLAGFILE}" 2>/dev/null)" || LAST_RUN=0

    if "${MK_FORCE_INVENTORY:-false}"; then
        "$@" | _insert_persist_option "${UNTIL}"
        return
    fi

    if [ $((NOW - LAST_RUN)) -lt "${INTERVAL}" ]; then
        return
    fi

    mkdir "${FLAGFILE%/*}"
    echo "${NOW}" >"${FLAGFILE}"

    "$@" | _insert_persist_option "${UNTIL}"
}

#
# END COMMON INVENTORY CODE
#

sections_mk_inventory() {
    section_solaris_uname

    section_solaris_prtdiag

    section_solaris_psrinfo

    section_solaris_pkginfo

    section_solaris_addresses

    section_solaris_routes
}

section_solaris_uname() {
    # SUP-22439: try and output the uname information from the uname
    # found on the path. If not available, fallback to the full path
    # because some users may override their PATH. If the underlying
    # binary is for whatever not there, the sections will not be
    # added to agent output.
    if uname -X &>/dev/null; then
        echo "<<<solaris_uname:sep(61)>>>"
        uname -X
    elif /usr/bin/uname -X &>/dev/null; then
        echo "<<<solaris_uname:sep(61)>>>"
        /usr/bin/uname -X
    fi
}

section_solaris_prtdiag() {
    inpath prtdiag && zoneadm list | grep -q global || return

    echo "<<<solaris_prtdiag:sep(10)>>>"
    if inpath sneep; then
        SN=$(sneep -t serial)
    else
        SN=$(smbios -t SMB_TYPE_SYSTEM | grep 'Serial Number:' | awk '{print substr($0, index($0,$3))}')
    fi
    echo "SerialNumber: $SN"
    prtdiag -v
}

section_solaris_psrinfo() {
    inpath psrinfo || return

    # Previously, we only had this single psrinfo section
    # Keep the name to avoid incompatibilities.
    echo "<<<solaris_psrinfo>>>"
    psrinfo -p -v

    # Name the section containing the plain "psrinfo" output
    # _virtual instead, as this is what it basically contains
    echo "<<<solaris_psrinfo_virtual>>>"
    psrinfo

    echo "<<<solaris_psrinfo_physical>>>"
    psrinfo -p

    # -t option is not available on older systems
    PSRINFO_T=$(psrinfo -t 2>/dev/null)
    if [ -n "$PSRINFO_T" ]; then
        echo "<<<solaris_psrinfo_table>>>"
        psrinfo -t
    fi

}

section_solaris_pkginfo() {
    inpath pkginfo || return
    echo "<<<solaris_pkginfo:sep(58)>>>"
    pkginfo -l
}

section_solaris_addresses() {
    echo "<<<solaris_addresses>>>"
    ifconfig -a
}

section_solaris_routes() {
    echo "<<<solaris_routes>>>"
    netstat -nr
}

#
# BEGIN COMMON INVENTORY CODE
#

main() {
    _load_config "${MK_CONFDIR}/mk_inventory.cfg"

    run_persisted "${INVENTORY_INTERVAL:?}" sections_mk_inventory
}

[ -z "${MK_SOURCE_AGENT}" ] && main
